{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "数据说明：某城市各企业用电数据，从2015-1-1至2016-8-31，任务是预测未来一个月（即2016-9月）的用电情况\n",
    "\n",
    "方法：特征工程+lightGBM\n",
    "\n",
    "lightGBM 安装：pip3 install lightgbm\n",
    "\n",
    "lightGBM官方文档：https://lightgbm.readthedocs.io/en/latest/Python-Intro.html\n",
    "\n",
    "lightGBM有2种Python API：1种是 sklearn 风格的Python API，还有一套自己原生的Python API\n",
    "\n",
    "下面是使用 sklearn 风格 Python API的示例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/xijian\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "from matplotlib import pyplot as plt\n",
    "import os\n",
    "print(os.getcwd())\n",
    "cwd = '/home/xijian/pycharm_projects/Magic-NLPer/MachineLearning/AdaBoost/'\n",
    "data_dir = cwd + 'data/'"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "outputs": [
    {
     "data": {
      "text/plain": "   user_id record_date  power_consumption\n0        1  2015-01-01             1135.0\n1        1  2015-01-02              570.0\n2        1  2015-01-03             3418.0\n3        1  2015-01-04             3968.0\n4        1  2015-01-05             3986.0",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>user_id</th>\n      <th>record_date</th>\n      <th>power_consumption</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>1</td>\n      <td>2015-01-01</td>\n      <td>1135.0</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>1</td>\n      <td>2015-01-02</td>\n      <td>570.0</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>1</td>\n      <td>2015-01-03</td>\n      <td>3418.0</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>1</td>\n      <td>2015-01-04</td>\n      <td>3968.0</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>1</td>\n      <td>2015-01-05</td>\n      <td>3986.0</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 加载数据\n",
    "df = pd.read_csv(data_dir + 'tianchi_power_AI.csv')\n",
    "# 格式转换  将时间字符串转换为pandas认识的时间字段/列\n",
    "df['record_date'] = pd.to_datetime(df['record_date'])\n",
    "df.head()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2015-01-01 00:00:00\n",
      "2016-08-31 00:00:00\n"
     ]
    },
    {
     "data": {
      "text/plain": "  record_date  power_consumption\n0  2015-01-01          2900575.0\n1  2015-01-02          3158211.0\n2  2015-01-03          3596487.0\n3  2015-01-04          3939672.0\n4  2015-01-05          4101790.0",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>record_date</th>\n      <th>power_consumption</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>2015-01-01</td>\n      <td>2900575.0</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>2015-01-02</td>\n      <td>3158211.0</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>2015-01-03</td>\n      <td>3596487.0</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>2015-01-04</td>\n      <td>3939672.0</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>2015-01-05</td>\n      <td>4101790.0</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 按每年每个月分组求和\n",
    "base_df = df[['record_date', 'power_consumption']].groupby(by='record_date').agg('sum')\n",
    "base_df = base_df.reset_index()\n",
    "print(base_df['record_date'].min())\n",
    "print(base_df['record_date'].max())\n",
    "base_df.head()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 特征工程\n",
    "\n",
    "直接对每天的总量进行回归拟合，先提取用以回归的特征"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:4: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  after removing the cwd from sys.path.\n"
     ]
    },
    {
     "data": {
      "text/plain": "    record_date  power_consumption\n578  2016-09-01          4627029.0\n579  2016-09-02          4618467.0\n580  2016-09-03          4490739.0\n581  2016-09-04          4367727.0\n582  2016-09-05          4253298.0",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>record_date</th>\n      <th>power_consumption</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>578</th>\n      <td>2016-09-01</td>\n      <td>4627029.0</td>\n    </tr>\n    <tr>\n      <th>579</th>\n      <td>2016-09-02</td>\n      <td>4618467.0</td>\n    </tr>\n    <tr>\n      <th>580</th>\n      <td>2016-09-03</td>\n      <td>4490739.0</td>\n    </tr>\n    <tr>\n      <th>581</th>\n      <td>2016-09-04</td>\n      <td>4367727.0</td>\n    </tr>\n    <tr>\n      <th>582</th>\n      <td>2016-09-05</td>\n      <td>4253298.0</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_test = base_df[ (base_df['record_date']>='2016-08-01') &\n",
    "                   (base_df['record_date']<='2016-08-30')]\n",
    "# Timedelta： 时间差类型\n",
    "df_test['record_date'] = df_test['record_date']+pd.Timedelta('31 days') # 8月日期转9月日期\n",
    "df_test.head()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [
    {
     "data": {
      "text/plain": "  record_date  power_consumption\n0  2015-01-01          2900575.0\n1  2015-01-02          3158211.0\n2  2015-01-03          3596487.0\n3  2015-01-04          3939672.0\n4  2015-01-05          4101790.0",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>record_date</th>\n      <th>power_consumption</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>2015-01-01</td>\n      <td>2900575.0</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>2015-01-02</td>\n      <td>3158211.0</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>2015-01-03</td>\n      <td>3596487.0</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>2015-01-04</td>\n      <td>3939672.0</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>2015-01-05</td>\n      <td>4101790.0</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "base_df = pd.concat([base_df, df_test]).sort_values(['record_date']) # 包含了2016-9月预测月\n",
    "base_df.head()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "outputs": [
    {
     "data": {
      "text/plain": "  record_date  power_consumption  dayofweek  dayofyear  day  month  year\n0  2015-01-01          2900575.0          3          1    1      1  2015\n1  2015-01-02          3158211.0          4          2    2      1  2015\n2  2015-01-03          3596487.0          5          3    3      1  2015\n3  2015-01-04          3939672.0          6          4    4      1  2015\n4  2015-01-05          4101790.0          0          5    5      1  2015",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>record_date</th>\n      <th>power_consumption</th>\n      <th>dayofweek</th>\n      <th>dayofyear</th>\n      <th>day</th>\n      <th>month</th>\n      <th>year</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>2015-01-01</td>\n      <td>2900575.0</td>\n      <td>3</td>\n      <td>1</td>\n      <td>1</td>\n      <td>1</td>\n      <td>2015</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>2015-01-02</td>\n      <td>3158211.0</td>\n      <td>4</td>\n      <td>2</td>\n      <td>2</td>\n      <td>1</td>\n      <td>2015</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>2015-01-03</td>\n      <td>3596487.0</td>\n      <td>5</td>\n      <td>3</td>\n      <td>3</td>\n      <td>1</td>\n      <td>2015</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>2015-01-04</td>\n      <td>3939672.0</td>\n      <td>6</td>\n      <td>4</td>\n      <td>4</td>\n      <td>1</td>\n      <td>2015</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>2015-01-05</td>\n      <td>4101790.0</td>\n      <td>0</td>\n      <td>5</td>\n      <td>5</td>\n      <td>1</td>\n      <td>2015</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 提取年、月、日、星期几、一月中的第几天、第几季度等特征\n",
    "base_df['dayofweek'] = base_df['record_date'].apply(lambda x: x.dayofweek)\n",
    "base_df['dayofyear'] = base_df['record_date'].apply(lambda x: x.dayofyear)\n",
    "base_df['day'] = base_df['record_date'].apply(lambda x: x.day)\n",
    "base_df['month'] = base_df['record_date'].apply(lambda x: x.month)\n",
    "base_df['year'] = base_df['record_date'].apply(lambda x: x.year)\n",
    "base_df.head()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [
    {
     "data": {
      "text/plain": "  record_date  power_consumption  dayofweek  dayofyear  day  month  year  \\\n0  2015-01-01          2900575.0          3          1    1      1  2015   \n1  2015-01-02          3158211.0          4          2    2      1  2015   \n2  2015-01-03          3596487.0          5          3    3      1  2015   \n3  2015-01-04          3939672.0          6          4    4      1  2015   \n4  2015-01-05          4101790.0          0          5    5      1  2015   \n\n   season  \n0       1  \n1       1  \n2       1  \n3       1  \n4       1  ",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>record_date</th>\n      <th>power_consumption</th>\n      <th>dayofweek</th>\n      <th>dayofyear</th>\n      <th>day</th>\n      <th>month</th>\n      <th>year</th>\n      <th>season</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>2015-01-01</td>\n      <td>2900575.0</td>\n      <td>3</td>\n      <td>1</td>\n      <td>1</td>\n      <td>1</td>\n      <td>2015</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>2015-01-02</td>\n      <td>3158211.0</td>\n      <td>4</td>\n      <td>2</td>\n      <td>2</td>\n      <td>1</td>\n      <td>2015</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>2015-01-03</td>\n      <td>3596487.0</td>\n      <td>5</td>\n      <td>3</td>\n      <td>3</td>\n      <td>1</td>\n      <td>2015</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>2015-01-04</td>\n      <td>3939672.0</td>\n      <td>6</td>\n      <td>4</td>\n      <td>4</td>\n      <td>1</td>\n      <td>2015</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>2015-01-05</td>\n      <td>4101790.0</td>\n      <td>0</td>\n      <td>5</td>\n      <td>5</td>\n      <td>1</td>\n      <td>2015</td>\n      <td>1</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 映射到第几季度\n",
    "def map_season(month):\n",
    "    month_dict = {1:1, 2:1, 3:1, 4:2, 5:2, 6:2, 7:3, 8:3, 9:3, 10:4, 11:4, 12:4}\n",
    "    return month_dict[month]\n",
    "\n",
    "base_df['season'] = base_df['month'].apply(lambda x: map_season(x))\n",
    "base_df.head()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    mean            std\n",
      "year month                             \n",
      "2015 1      3.961383e+06  303629.486622\n",
      "     2      2.795163e+06  769697.864999\n",
      "     3      3.478852e+06  564753.747993\n",
      "     4      3.768333e+06  190787.832757\n",
      "     5      3.755262e+06  269088.249265\n"
     ]
    },
    {
     "data": {
      "text/plain": "   year  month          mean            std\n0  2015      1  3.961383e+06  303629.486622\n1  2015      2  2.795163e+06  769697.864999\n2  2015      3  3.478852e+06  564753.747993\n3  2015      4  3.768333e+06  190787.832757\n4  2015      5  3.755262e+06  269088.249265",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>year</th>\n      <th>month</th>\n      <th>mean</th>\n      <th>std</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>2015</td>\n      <td>1</td>\n      <td>3.961383e+06</td>\n      <td>303629.486622</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>2015</td>\n      <td>2</td>\n      <td>2.795163e+06</td>\n      <td>769697.864999</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>2015</td>\n      <td>3</td>\n      <td>3.478852e+06</td>\n      <td>564753.747993</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>2015</td>\n      <td>4</td>\n      <td>3.768333e+06</td>\n      <td>190787.832757</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>2015</td>\n      <td>5</td>\n      <td>3.755262e+06</td>\n      <td>269088.249265</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 按每年每月分组 计算统计信息：均值、标准差\n",
    "base_df_stats = base_df[ ['power_consumption', 'year', 'month'] ].groupby(by=['year', 'month']).agg(['mean', 'std'])\n",
    "base_df_stats.columns = base_df_stats.columns.droplevel(0)\n",
    "print(base_df_stats.head())\n",
    "base_df_stats = base_df_stats.reset_index()\n",
    "base_df_stats.head()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "outputs": [
    {
     "data": {
      "text/plain": "   year  month          mean            std      1_m_mean      2_m_mean  \\\n0  2015      1  3.961383e+06  303629.486622           NaN           NaN   \n1  2015      2  2.795163e+06  769697.864999  3.961383e+06           NaN   \n2  2015      3  3.478852e+06  564753.747993  2.795163e+06  3.961383e+06   \n3  2015      4  3.768333e+06  190787.832757  3.478852e+06  2.795163e+06   \n4  2015      5  3.755262e+06  269088.249265  3.768333e+06  3.478852e+06   \n\n         1_m_std        2_m_std  \n0            NaN            NaN  \n1  303629.486622            NaN  \n2  769697.864999  303629.486622  \n3  564753.747993  769697.864999  \n4  190787.832757  564753.747993  ",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>year</th>\n      <th>month</th>\n      <th>mean</th>\n      <th>std</th>\n      <th>1_m_mean</th>\n      <th>2_m_mean</th>\n      <th>1_m_std</th>\n      <th>2_m_std</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>2015</td>\n      <td>1</td>\n      <td>3.961383e+06</td>\n      <td>303629.486622</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>2015</td>\n      <td>2</td>\n      <td>2.795163e+06</td>\n      <td>769697.864999</td>\n      <td>3.961383e+06</td>\n      <td>NaN</td>\n      <td>303629.486622</td>\n      <td>NaN</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>2015</td>\n      <td>3</td>\n      <td>3.478852e+06</td>\n      <td>564753.747993</td>\n      <td>2.795163e+06</td>\n      <td>3.961383e+06</td>\n      <td>769697.864999</td>\n      <td>303629.486622</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>2015</td>\n      <td>4</td>\n      <td>3.768333e+06</td>\n      <td>190787.832757</td>\n      <td>3.478852e+06</td>\n      <td>2.795163e+06</td>\n      <td>564753.747993</td>\n      <td>769697.864999</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>2015</td>\n      <td>5</td>\n      <td>3.755262e+06</td>\n      <td>269088.249265</td>\n      <td>3.768333e+06</td>\n      <td>3.478852e+06</td>\n      <td>190787.832757</td>\n      <td>564753.747993</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "base_df_stats['1_m_mean'] = base_df_stats['mean'].shift(1) # 向下移动1\n",
    "base_df_stats['2_m_mean'] = base_df_stats['mean'].shift(2) # 向下移动2\n",
    "base_df_stats['1_m_std'] = base_df_stats['std'].shift(1) # 向下移动1\n",
    "base_df_stats['2_m_std'] = base_df_stats['std'].shift(2) # 向下移动2\n",
    "base_df_stats.head()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  record_date  power_consumption  dayofweek  dayofyear  day  month  year  \\\n",
      "0  2015-01-01          2900575.0          3          1    1      1  2015   \n",
      "1  2015-01-02          3158211.0          4          2    2      1  2015   \n",
      "2  2015-01-03          3596487.0          5          3    3      1  2015   \n",
      "3  2015-01-04          3939672.0          6          4    4      1  2015   \n",
      "4  2015-01-05          4101790.0          0          5    5      1  2015   \n",
      "\n",
      "   season  1_m_mean  2_m_mean  1_m_std  2_m_std  \n",
      "0       1       NaN       NaN      NaN      NaN  \n",
      "1       1       NaN       NaN      NaN      NaN  \n",
      "2       1       NaN       NaN      NaN      NaN  \n",
      "3       1       NaN       NaN      NaN      NaN  \n",
      "4       1       NaN       NaN      NaN      NaN  \n"
     ]
    },
    {
     "data": {
      "text/plain": "   record_date  power_consumption  dayofweek  dayofyear  day  month  year  \\\n59  2015-03-01          2900464.0          6         60    1      3  2015   \n60  2015-03-02          3334082.0          0         61    2      3  2015   \n61  2015-03-03          3492606.0          1         62    3      3  2015   \n62  2015-03-04          3597890.0          2         63    4      3  2015   \n63  2015-03-05          1798044.0          3         64    5      3  2015   \n\n    season      1_m_mean      2_m_mean        1_m_std        2_m_std  \n59       1  2.795163e+06  3.961383e+06  769697.864999  303629.486622  \n60       1  2.795163e+06  3.961383e+06  769697.864999  303629.486622  \n61       1  2.795163e+06  3.961383e+06  769697.864999  303629.486622  \n62       1  2.795163e+06  3.961383e+06  769697.864999  303629.486622  \n63       1  2.795163e+06  3.961383e+06  769697.864999  303629.486622  ",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>record_date</th>\n      <th>power_consumption</th>\n      <th>dayofweek</th>\n      <th>dayofyear</th>\n      <th>day</th>\n      <th>month</th>\n      <th>year</th>\n      <th>season</th>\n      <th>1_m_mean</th>\n      <th>2_m_mean</th>\n      <th>1_m_std</th>\n      <th>2_m_std</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>59</th>\n      <td>2015-03-01</td>\n      <td>2900464.0</td>\n      <td>6</td>\n      <td>60</td>\n      <td>1</td>\n      <td>3</td>\n      <td>2015</td>\n      <td>1</td>\n      <td>2.795163e+06</td>\n      <td>3.961383e+06</td>\n      <td>769697.864999</td>\n      <td>303629.486622</td>\n    </tr>\n    <tr>\n      <th>60</th>\n      <td>2015-03-02</td>\n      <td>3334082.0</td>\n      <td>0</td>\n      <td>61</td>\n      <td>2</td>\n      <td>3</td>\n      <td>2015</td>\n      <td>1</td>\n      <td>2.795163e+06</td>\n      <td>3.961383e+06</td>\n      <td>769697.864999</td>\n      <td>303629.486622</td>\n    </tr>\n    <tr>\n      <th>61</th>\n      <td>2015-03-03</td>\n      <td>3492606.0</td>\n      <td>1</td>\n      <td>62</td>\n      <td>3</td>\n      <td>3</td>\n      <td>2015</td>\n      <td>1</td>\n      <td>2.795163e+06</td>\n      <td>3.961383e+06</td>\n      <td>769697.864999</td>\n      <td>303629.486622</td>\n    </tr>\n    <tr>\n      <th>62</th>\n      <td>2015-03-04</td>\n      <td>3597890.0</td>\n      <td>2</td>\n      <td>63</td>\n      <td>4</td>\n      <td>3</td>\n      <td>2015</td>\n      <td>1</td>\n      <td>2.795163e+06</td>\n      <td>3.961383e+06</td>\n      <td>769697.864999</td>\n      <td>303629.486622</td>\n    </tr>\n    <tr>\n      <th>63</th>\n      <td>2015-03-05</td>\n      <td>1798044.0</td>\n      <td>3</td>\n      <td>64</td>\n      <td>5</td>\n      <td>3</td>\n      <td>2015</td>\n      <td>1</td>\n      <td>2.795163e+06</td>\n      <td>3.961383e+06</td>\n      <td>769697.864999</td>\n      <td>303629.486622</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_df = pd.merge(base_df, base_df_stats[ ['year', 'month', '1_m_mean', '2_m_mean', '1_m_std', '2_m_std'] ],\n",
    "                   how='inner', on=['year', 'month'])\n",
    "print(data_df.head())\n",
    "data_df = data_df[~pd.isnull(data_df['2_m_mean'])] # 去掉Nan数据\n",
    "data_df.head()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "outputs": [
    {
     "data": {
      "text/plain": "    record_date  power_consumption  dayofweek  dayofyear  day  month  year  \\\n634  2016-09-26          4018774.0          0        270   26      9  2016   \n635  2016-09-27          3610828.0          1        271   27      9  2016   \n636  2016-09-28          3446470.0          2        272   28      9  2016   \n637  2016-09-29          3681879.0          3        273   29      9  2016   \n638  2016-09-30          3607667.0          4        274   30      9  2016   \n\n     season      1_m_mean      2_m_mean        1_m_std        2_m_std  \n634       3  4.072800e+06  4.458408e+06  337880.572544  276925.542329  \n635       3  4.072800e+06  4.458408e+06  337880.572544  276925.542329  \n636       3  4.072800e+06  4.458408e+06  337880.572544  276925.542329  \n637       3  4.072800e+06  4.458408e+06  337880.572544  276925.542329  \n638       3  4.072800e+06  4.458408e+06  337880.572544  276925.542329  ",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>record_date</th>\n      <th>power_consumption</th>\n      <th>dayofweek</th>\n      <th>dayofyear</th>\n      <th>day</th>\n      <th>month</th>\n      <th>year</th>\n      <th>season</th>\n      <th>1_m_mean</th>\n      <th>2_m_mean</th>\n      <th>1_m_std</th>\n      <th>2_m_std</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>634</th>\n      <td>2016-09-26</td>\n      <td>4018774.0</td>\n      <td>0</td>\n      <td>270</td>\n      <td>26</td>\n      <td>9</td>\n      <td>2016</td>\n      <td>3</td>\n      <td>4.072800e+06</td>\n      <td>4.458408e+06</td>\n      <td>337880.572544</td>\n      <td>276925.542329</td>\n    </tr>\n    <tr>\n      <th>635</th>\n      <td>2016-09-27</td>\n      <td>3610828.0</td>\n      <td>1</td>\n      <td>271</td>\n      <td>27</td>\n      <td>9</td>\n      <td>2016</td>\n      <td>3</td>\n      <td>4.072800e+06</td>\n      <td>4.458408e+06</td>\n      <td>337880.572544</td>\n      <td>276925.542329</td>\n    </tr>\n    <tr>\n      <th>636</th>\n      <td>2016-09-28</td>\n      <td>3446470.0</td>\n      <td>2</td>\n      <td>272</td>\n      <td>28</td>\n      <td>9</td>\n      <td>2016</td>\n      <td>3</td>\n      <td>4.072800e+06</td>\n      <td>4.458408e+06</td>\n      <td>337880.572544</td>\n      <td>276925.542329</td>\n    </tr>\n    <tr>\n      <th>637</th>\n      <td>2016-09-29</td>\n      <td>3681879.0</td>\n      <td>3</td>\n      <td>273</td>\n      <td>29</td>\n      <td>9</td>\n      <td>2016</td>\n      <td>3</td>\n      <td>4.072800e+06</td>\n      <td>4.458408e+06</td>\n      <td>337880.572544</td>\n      <td>276925.542329</td>\n    </tr>\n    <tr>\n      <th>638</th>\n      <td>2016-09-30</td>\n      <td>3607667.0</td>\n      <td>4</td>\n      <td>274</td>\n      <td>30</td>\n      <td>9</td>\n      <td>2016</td>\n      <td>3</td>\n      <td>4.072800e+06</td>\n      <td>4.458408e+06</td>\n      <td>337880.572544</td>\n      <td>276925.542329</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_df.tail()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### lightGBM"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "outputs": [],
   "source": [
    "import lightgbm as lgb\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "train_data = data_df[data_df['record_date']<'2016-09-01']\\\n",
    "    [['dayofweek','dayofyear','day','month','year','season','1_m_mean','2_m_mean','1_m_std','2_m_std']]\n",
    "test_data = data_df[data_df['record_date']>='2016-09-01']\\\n",
    "    [['dayofweek','dayofyear','day','month','year','season','1_m_mean','2_m_mean','1_m_std','2_m_std']]\n",
    "train_target = data_df[data_df['record_date']<'2016-09-01'][ ['power_consumption'] ]"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "outputs": [],
   "source": [
    "\n",
    "train_lgb = train_data.copy()\n",
    "# 日期/时间格式转换为str类型\n",
    "train_lgb[ ['dayofweek','dayofyear','day','month','year','season'] ] = \\\n",
    "    train_lgb[ ['dayofweek','dayofyear','day','month','year','season'] ].astype(str)\n",
    "test_lgb = test_data.copy()\n",
    "test_lgb[ ['dayofweek','dayofyear','day','month','year','season'] ] = \\\n",
    "    test_lgb[ ['dayofweek','dayofyear','day','month','year','season'] ].astype(str)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(550, 10) (550,) <class 'numpy.ndarray'>\n",
      "['6' '60' '1' '3' '2015' '1' 2795163.0535714286 3961383.0967741935\n",
      " 769697.8649992085 303629.48662213905]\n"
     ]
    }
   ],
   "source": [
    "X_lgb = train_lgb.values\n",
    "y_lgb = train_target.values.reshape(X_lgb.shape[0],)\n",
    "print(X_lgb.shape, y_lgb.shape, type(X_lgb))\n",
    "print(X_lgb[0, :])"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "outputs": [],
   "source": [
    "\n",
    "# 模型参数\n",
    "estimator = lgb.LGBMRegressor(colsample_bytree=0.8, # 建每棵树时使用的属性列的比例（属性采样比例）\n",
    "                             subsample=0.9, # 使用训练样本的比例（样本采样比例）\n",
    "                             subsample_freq=5) # 采样频率\n",
    "param_grid = {\n",
    "    'learning_rate': [0.01, 0.02, 0.05, 0.1],\n",
    "    'n_estimators': [100, 200, 400, 800, 1000, 1200, 1500, 2000], # 要学习的boosted trees 个数\n",
    "    'num_leaves': [128, 1024, 4096], # base learner的最大叶子节点数\n",
    "}\n",
    "\n",
    "# 训练参数\n",
    "fit_params = {'categorical_feature': [0,1,2,3,4,5]} # 哪些列是类别型特征，list of int则表示索引"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Best parameters found by grid search are: {'learning_rate': 0.02, 'n_estimators': 1200, 'num_leaves': 128}\n"
     ]
    }
   ],
   "source": [
    "\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\") # 不打印warning信息\n",
    "\n",
    "gbm = GridSearchCV(estimator, param_grid)\n",
    "\n",
    "gbm.fit(X_lgb, y_lgb, **fit_params)\n",
    "\n",
    "print('Best parameters found by grid search are:', gbm.best_params_)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "outputs": [
    {
     "data": {
      "text/plain": "LGBMRegressor(colsample_bytree=0.8, learning_rate=0.02, n_estimators=1200,\n              num_leaves=128, objective='regression_l1', subsample=0.9,\n              subsample_freq=5)"
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用最佳参数，重新训练模型\n",
    "lgbm = lgb.LGBMRegressor(colsample_bytree=0.8, # 建每棵树时使用的属性列的比例（属性采样比例）\n",
    "                         subsample=0.9, # 使用训练样本的比例（样本采样比例）\n",
    "                         subsample_freq=5, # 采样频率\n",
    "                         learning_rate=0.02,\n",
    "                         n_estimators=1200,\n",
    "                         num_leaves=128,\n",
    "                         objective='regression_l1'\n",
    "                         )\n",
    "lgbm.fit(X_lgb, y_lgb)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(30, 10)\n",
      "(30,)\n"
     ]
    }
   ],
   "source": [
    "X_pred = test_lgb.values\n",
    "print(X_pred.shape)\n",
    "y_pred = lgbm.predict(X_pred)\n",
    "print(y_pred.shape)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Plot feature importances...\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "print('Plot feature importances...')\n",
    "ax = lgb.plot_importance(lgbm, max_num_features=5) # max_num_features 显示最重要的5个特征\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}